package com.bhh.myservlet.connector;

import com.bhh.myservlet.requestandresponse.Request;
import com.bhh.myservlet.requestandresponse.Response;
import com.bhh.myservlet.processor.ServletProcessor;
import com.bhh.myservlet.processor.StaticProcessor;
import lombok.extern.slf4j.Slf4j;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author bhh
 * @description 实现Connector
 * <p>
 * 处理Request和Response
 * @date Created in 2021-04-15 12:45
 * @modified By
 */
@Slf4j
public class Connector implements Runnable {

    private static final int DEFAULT_PORT = 8888;

    private ServerSocket server;
    private int port;

    public Connector(int port) {
        this.port = port;
    }

    public Connector() {
        this(DEFAULT_PORT);
    }

    @Override
    public void run() {
        try {
            server = new ServerSocket(port);
            log.info("服务器成功启动, 监听端口 : " + port);

            while (true) {
                Socket client = server.accept();
                InputStream inputStream = client.getInputStream();
                OutputStream outputStream = client.getOutputStream();

                Request request = new Request(inputStream);
                request.parse();

                Response response = new Response(outputStream);
                response.setRequest(request);

                if (request.getUri().startsWith("/servlet/")){
                    ServletProcessor processor = new ServletProcessor();
                    processor.process(request, response);
                }else {
                    StaticProcessor processor = new StaticProcessor();
                    processor.process(request, response);
                }

                close(client);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close(server);
        }
    }

    /**
     * 关闭流
     *
     * @param closeable
     */
    public void close(Closeable closeable) {
        try {
            closeable.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start() {
        new Thread(this).start();
    }
}
